package data

import (
	"fmt"
	"reflect"

	"gitee.com/miajio/go-util/lib/read"
)

// distinctInterface 去重结构体接口
type distinctInterface interface {
	dist(slice interface{}) ([]interface{}, error) // dist 内核去重方法
	String(vals ...string) []string                // String 去重字符串数组
	Int(vals ...int) []int                         // Int 去重整数数组
	Int8(vals ...int8) []int8                      // Int8 去重整数数组
	Int16(vals ...int16) []int16                   // Int8 去重整数数组
	Int32(vals ...int32) []int32                   // Int32 去重整数数组
	Int64(vals ...int64) []int64                   // Int64 去重整数数组
	Uint(vals ...uint) []uint                      // Uint 去重整数数组
	Uint8(vals ...uint8) []uint8                   // Uint8 去重整数数组
	Uint16(vals ...uint16) []uint16                // Uint16 去重整数数组
	Uint32(vals ...uint32) []uint32                // Uint32 去重整数数组
	Uint64(vals ...uint64) []uint64                // Uint64 去重整数数组
	Byte(vals ...byte) []byte                      // Byte 去重字节数组
	Float32(vals ...float32) []float32             // Float32 去重浮点数组
	Float64(vals ...float64) []float64             // Float64 去重浮点数组
}

// distinct 去重结构体
type distinct struct{}

// Distinct 去重操作对象
var Distinct distinctInterface = (*distinct)(nil)

// String 去重字符串数组
func (distinct *distinct) String(vals ...string) []string {
	if len(vals) > 1 {
		interfaceSlice, _ := distinct.dist(vals)
		return read.Slice.InterfaceToString(interfaceSlice)
	} else {
		return vals
	}
}

// Int 去重字符串数组
func (distinct *distinct) Int(vals ...int) []int {
	if len(vals) > 1 {
		interfaceSlice, _ := distinct.dist(vals)
		return read.Slice.InterfaceToInt(interfaceSlice)
	} else {
		return vals
	}
}

// Int8 去重字符串数组
func (distinct *distinct) Int8(vals ...int8) []int8 {
	if len(vals) > 1 {
		interfaceSlice, _ := distinct.dist(vals)
		return read.Slice.InterfaceToInt8(interfaceSlice)
	} else {
		return vals
	}
}

// Int16 去重字符串数组
func (distinct *distinct) Int16(vals ...int16) []int16 {
	if len(vals) > 1 {
		interfaceSlice, _ := distinct.dist(vals)
		return read.Slice.InterfaceToInt16(interfaceSlice)
	} else {
		return vals
	}
}

// Int32 去重字符串数组
func (distinct *distinct) Int32(vals ...int32) []int32 {
	if len(vals) > 1 {
		interfaceSlice, _ := distinct.dist(vals)
		return read.Slice.InterfaceToInt32(interfaceSlice)
	} else {
		return vals
	}
}

// Int64 去重字符串数组
func (distinct *distinct) Int64(vals ...int64) []int64 {
	if len(vals) > 1 {
		interfaceSlice, _ := distinct.dist(vals)
		return read.Slice.InterfaceToInt64(interfaceSlice)
	} else {
		return vals
	}
}

// Uint 去重字符串数组
func (distinct *distinct) Uint(vals ...uint) []uint {
	if len(vals) > 1 {
		interfaceSlice, _ := distinct.dist(vals)
		return read.Slice.InterfaceToUint(interfaceSlice)
	} else {
		return vals
	}
}

// Uint8 去重字符串数组
func (distinct *distinct) Uint8(vals ...uint8) []uint8 {
	if len(vals) > 1 {
		interfaceSlice, _ := distinct.dist(vals)
		return read.Slice.InterfaceToUint8(interfaceSlice)
	} else {
		return vals
	}
}

// Uint16 去重字符串数组
func (distinct *distinct) Uint16(vals ...uint16) []uint16 {
	if len(vals) > 1 {
		interfaceSlice, _ := distinct.dist(vals)
		return read.Slice.InterfaceToUint16(interfaceSlice)
	} else {
		return vals
	}
}

// Uint32 去重字符串数组
func (distinct *distinct) Uint32(vals ...uint32) []uint32 {
	if len(vals) > 1 {
		interfaceSlice, _ := distinct.dist(vals)
		return read.Slice.InterfaceToUint32(interfaceSlice)
	} else {
		return vals
	}
}

// Uint64 去重字符串数组
func (distinct *distinct) Uint64(vals ...uint64) []uint64 {
	if len(vals) > 1 {
		interfaceSlice, _ := distinct.dist(vals)
		return read.Slice.InterfaceToUint64(interfaceSlice)
	} else {
		return vals
	}
}

// Byte 去重字节数组
func (distinct *distinct) Byte(vals ...byte) []byte {
	if len(vals) > 1 {
		interfaceSlice, _ := distinct.dist(vals)
		return read.Slice.InterfaceToByte(interfaceSlice)
	} else {
		return vals
	}
}

// Float32 去重浮点数组
func (distinct *distinct) Float32(vals ...float32) []float32 {
	if len(vals) > 1 {
		interfaceSlice, _ := distinct.dist(vals)
		return read.Slice.InterfaceToFloat32(interfaceSlice)
	} else {
		return vals
	}
}

// Float64 去重浮点数组
func (distinct *distinct) Float64(vals ...float64) []float64 {
	if len(vals) > 1 {
		interfaceSlice, _ := distinct.dist(vals)
		return read.Slice.InterfaceToFloat64(interfaceSlice)
	} else {
		return vals
	}
}

// dist 内核去重方法
func (*distinct) dist(slice interface{}) ([]interface{}, error) {
	result := make([]interface{}, 0)
	switch reflect.TypeOf(slice).Kind() {
	case reflect.Slice, reflect.Array:
		vals := reflect.ValueOf(slice)
		for i := 0; i < vals.Len(); i++ {
			val := vals.Index(i).Interface()
			have := false
			for j := range result {
				if val == result[j] {
					have = true
					break
				}
			}
			if !have {
				result = append(result, val)
			}
		}
	default:
		return nil, fmt.Errorf("slice type error")
	}
	return result, nil
}
